package code17_reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.HashSet;

public class Homework02 {

	/**
	 * 输出类的简单结构
	 * 例如: 
	 * <pre>
	 * Stu.class -->
	 * package code17_reflect;
	 * import java.io.Serializable;
	 * public class Stu extends Person implements Serializable, Cloneable {
	 *     public String name;
	 *     private int age;
	 *     ...
	 * }
	 * </pre>
	 * @param c
	 */
	public static void printClass(Class<?> c) {
		// 输出时, 要输出该类的导包信息. 不是所有的类都需要导包!
		HashSet<Class<?>> set = new HashSet<Class<?>>();
		
		StringBuffer buffer = new StringBuffer();
		
		String s1 = ";";
		String s2 = " ";
		Package pkg = c.getPackage();
		System.out.println("package" + s2 + pkg.getName() + s1);
		
		String classModifiers = Modifier.toString(c.getModifiers());
		buffer.append(classModifiers);
		buffer.append(s2);
		
		buffer.append("class");
		buffer.append(s2);
		
		String classSimpleName = c.getSimpleName();
		buffer.append(classSimpleName);
		buffer.append(s2);
		
		Class<?> superclass = c.getSuperclass();
		if (null != superclass && Object.class != superclass) {
			set.add(superclass);
			
			String superClassSimpleName = superclass.getSimpleName();
			buffer.append("extends");
			buffer.append(s2);
			buffer.append(superClassSimpleName);
			buffer.append(s2);
		}
		
		Class<?>[] interfaces = c.getInterfaces();
		if (interfaces.length > 0) {
			buffer.append("implements");
			buffer.append(s2);
			for (int i = 0; i < interfaces.length; i++) {
				Class<?> ci = interfaces[i];
				
				set.add(ci);
				
				String ciSimpleName = ci.getSimpleName();
				buffer.append(ciSimpleName);
				if (i < interfaces.length - 1) {
					buffer.append(",");
				}
				
				buffer.append(s2);
			}
		}
		buffer.append("{").append("\n");
		
		// 属性
		Field[] fields = c.getDeclaredFields();
		
		for (Field f : fields) {
			int modifiers = f.getModifiers();
			buffer.append("\t");
			
			buffer.append(Modifier.toString(modifiers));
			buffer.append(" ");
			
			Class<?> fieldType = f.getType();
			buffer.append(fieldType.getSimpleName());
			buffer.append(" ");
			
			set.add(fieldType);
			
			String name = f.getName();
			buffer.append(name);
			buffer.append(s1).append("\n");
		}
		
		// 方法
		Method[] methods = c.getDeclaredMethods();

		for (Method m : methods) {
			buffer.append("\t");
			String modifiers = Modifier.toString(m.getModifiers());
			Class<?> returnType = m.getReturnType();
			
			set.add(returnType);
			
			String name = m.getName();
			//Parameter[] parameters = m.getParameters();
			Class<?>[] parameterTypes = m.getParameterTypes();
			Class<?>[] exceptionTypes = m.getExceptionTypes();
			buffer.append(
					modifiers + " "
					+ returnType.getSimpleName() + " "
					+ name + "("
					//+ Arrays.toString(parameterTypes) + ") "
					//+ "throws " + Arrays.toString(exceptionTypes) + " { }"
					);
			
			// 参数
			if (parameterTypes.length > 0) {
				for (int j = 0; j < parameterTypes.length; j++) {
					Class<?> pt = parameterTypes[j];
					
					set.add(pt);
					
					buffer.append(pt.getSimpleName());
					buffer.append(" arg"+j);
					
					if (j < parameterTypes.length - 1) {
						buffer.append(",");
						buffer.append(s2);
					}
				}
			}
			buffer.append(")");
			
			// 异常
			if (exceptionTypes.length > 0) {
				buffer.append(" throws ");
				for (int i = 0; i < exceptionTypes.length; i++) {
					Class<?> et = exceptionTypes[i];
					
					set.add(et);
					
					buffer.append(et.getSimpleName());
					if (i < exceptionTypes.length - 1) {
						buffer.append(",");
						buffer.append(s2);
					}
				}
			}
			
			buffer.append(" {} ").append("\n");
		}
		
		// 构造方法
		Constructor<?>[] constructors = c.getDeclaredConstructors();
		for (Constructor<?> cr : constructors) {
			buffer.append("\t");
			
			String modifier = Modifier.toString(cr.getModifiers());
			buffer.append(modifier);
			buffer.append(s2);
			buffer.append(classSimpleName);
			buffer.append("(");
			
			Parameter[] parameters = cr.getParameters();
			for (int i = 0; i < parameters.length; i++) {
				Parameter param = parameters[i];
				buffer.append(param.getType().getSimpleName());
				buffer.append(" ");
				buffer.append(param.getName());
				
				set.add(param.getType());
				
				if (i < parameters.length - 1) {
					buffer.append(",");
					buffer.append(s2);
				}
			}
			buffer.append("){ }").append("\n");
		}
		
		buffer.append("}");
		
		// 输出导包
		for (Class<?> type : set) {
			String name = type.getName();
			if (null == type.getPackage()) {
				continue;
			}
			String pkgName = type.getPackage().getName();
			// 需要导包的才导包
			if ( !"void".equals(name) && !"byte".equals(name)
					&& !"short".equals(name)
					&& !"char".equals(name)
					&& !"int".equals(name)
					&& !"long".equals(name)
					&& !"float".equals(name)
					&& !"double".equals(name)
					&& !"boolean".equals(name)
					
					&& !"java.lang".equals(pkgName)
					
					&& !pkg.getName().equals(pkgName)
					
					) {
				System.out.print("import");
				System.out.print(s2);
				System.out.print(name);
				System.out.println(s1);
			}
		}
		
		// 输出类的结构
		System.out.println(buffer);
	}
	public static void main(String[] args) {
		printClass(Stu.class);
		
		printClass(String.class);
		
		printClass(Object.class);
	}
	
}
